#ifndef MAP_H
#define MAP_H

//#include <QDebug>
#include <QtGui/QGraphicsView>
#include <QTimer>
#include <QGestureEvent>
#include <QPinchGesture>

#include "mapelement.h"

class TMapLayer;
class TMapRoute;
class TMapNode;
class TMapEdge;
class FlickCharm;
//class TMapElement;


enum DrawType
{dtPenColor,dtBrushColor,dtLine,dtDashed,dtPolygon,dtSpline,dtEllipse,dtTextOut,dtAngleTextOut,dtOpaque,
 dtPeOpaqueAngleTextOut,dtImage,dtRailway,dtStairs,dtAngle,dtTranslate,dtPath,dtArrow,dtSpotCircle,dtSpotRect};

struct TPaintCmd
{
  QString param;
  DrawType type;

  QList<qreal> nums;
  QList<QColor> colors;
  QList<QString> strings;

  QPixmap *image;
  QPen pen;
  QBrush brush;
  QFont font;
  QPolygonF polygon;
  QPainterPath path;

};

class TMapView : public QGraphicsView
{
Q_OBJECT
 //friend class TMapElement;
 //friend void TMapElement::drawPaintCmd(QPainter *painter, QList<TPaintCmd> &paintCmd);

private:

    int timerId;

    struct AddCacheEdge
    {
     QString routeName[2];
     QString nodeName[2];
     QPolygon points;
     int edgeStyle;

     QString cost[2];
     bool transfer;

     bool assigned;
    };

    QList<AddCacheEdge*> edgeCache; // cache for additional nodes & transfers
    QHash<QChar, QString> BGN;
    QString WindowTitle;

    //void drawMapLayer(QPainter *painter, TMapLayer *mapLayer);

    void dijkstra(int nodeBeginID);
    QString convertToTextWithTags(QString text);

public:
    TMapView(QString AppPath, QString CachePath);
    ~TMapView();
    bool viewportEvent(QEvent *event);
    bool gestureEvent(QGestureEvent *event);
    void pinchTriggered(QPinchGesture *gesture);

    void scaleMap(qreal scaleFactor);
    void defaultConfig();
    void applyConfig();
    void loadMap(QString fileName);
    void loadMapImageToPaintCmd(QString imageFile, QList<TPaintCmd> &paintCmd);
    void loadMapLayers(QString LayerFilesTRP); // !! IN LAYER CLASS
    void initNodeInfo();
    void loadNodeInfo(TMapNode *node);

    void clearMap(); // !! DESTRUCT

    bool extractFiles(QString zipFile, QString extractFiles, QString extractDir);
    void exportMap(QString fileName,QString ext);
    void addPaintCmd(const QString &eParam,DrawType eType,QList<TPaintCmd> &paintCmd);
    void addLayerToPaintCmd(TMapLayer *mapLayer,QList<TPaintCmd> &paintCmd);
    void drawPaintCmd(QPainter *painter, QList<TPaintCmd> &paintCmd);
    int  strTimeToSec(const QString &strTime);

    void findTrack(TMapNode *begin,TMapNode *end=NULL);
    void clearTrack();
    void selectedNodesToFront(bool enable);

    void initTranslit();
    void convertToTranslit(QString &text);

    QTimer TimerPopup, TimerDragging;

    QList<TMapLayer*> layer;
    QList<TPaintCmd> paintBkg,paintMap;
    QList< QPair<QString,QColor> > getNamesAndColors();

    QVector< QVector<TMapEdge*> > mapGraph;
    QVector< QVector<qreal> > workGraph;
    QVector<qreal> mapDistance;
    QVector<int> mapParentNode;
    QVector<TMapNode*> nodeByID;
    QList<TMapNode*> selectedNode;
    QList<TMapEdge*> selectedEdge;

    QGraphicsScene *scene;
    QPixmap *CachedMap;
    //QImage *CachedMap;

    struct TParams
    {
     QString mapFile;
     QString mapPath;
     QString mapCachePath;
     QString mapName;
     QString mapCityName;
     QString mapCityDisplay;
     QString mapCountryName;
     QString mapRusName;
     QString mapNeedVersion;
     QString mapAuthors;
     QString mapDelayNames;
     QColor  mapColorBack;
     bool    mapIsVector;
     qreal   mapZoomFactor;

     qreal  nodeWidth;
     qreal  nodeConstructWidth;
     qreal  routeWidth;
     QFont  nodeFont;    // +UpperCase
     QFont  nodeFontDefault;
     int    nodeFontStyle; // +WordWrap
     QFont  nodeTimeFont;
     QColor nodeColorBack;
     QColor nodeColorShadow;
     bool   nodeUpperCase;
     bool   nodeWordWrap;



     QString Transports;
     QString CheckedTransports;

     QString appPath;
     QString appName;

     int delayMetro;
     int delayIndex;
    };

    TParams params;

    struct TConfig
    {
     QString mapLastFile;

//     QFont fontNode;
     int valueTransparency;

     bool enableCustomFont;
     bool enableStationBackColor;
     bool enableStationShadowColor;

     bool enableLowqDrag;
     bool enableDrawBackground;
     bool enableShowScrollBar;
     bool enableAntialiasing;
     bool enableSimpleTransfer;
     bool enableSimpleNode;
     bool enableWriteTime;
     bool enableTranslit;
     bool enableCaching;

     bool enableKineticScroll;

     bool MobileVersion;
     QString locale;


     //bool enableTransliterate;
     //bool enableCaptionHint;
    };
    TConfig config;

    struct TMapState
    {
     bool mapLoaded;
     bool mapCached;
     bool mapDragging;
     bool nodeClick;
    };
    TMapState state;

    QPoint nodeClickPos;
    int nodeBeginID, nodeEndID;
    TMapNode *nodeBegin,*nodeEnd,*nodeClick;
    TMapElement *mapFade;

    QTextCodec *codePage;
    QMenu *nodePopup;
    FlickCharm *fcharm;

public slots:
 void setDelayMetro(int delay);
 void setDelayIndex(int index);
 void zoomIn();
 void zoomOut();
 void fitMap();
 void setNodeBegin(TMapNode *Node=NULL);
 void setNodeEnd(TMapNode *Node=NULL);
 void popupByTimer();
 void saveToFile();
 void findTrackByID(int ID) { findTrack(nodeByID[ID]); }
 void findedNodesToFront(QList<int> NodeID);
 void mapStartDragging();
 void mapStopDragging();

signals:
 void trackInfo(QString Info);
 void trackDescription(QString Description);
 void trackText(QString Text);
 void trackFinded(bool Check);
 void delayNames(QStringList);
 void nodeClicked(bool clicked);
 void nodeHasInfo(bool HasInfo);

protected:
    void keyPressEvent(QKeyEvent *event);
    void wheelEvent(QWheelEvent *event);
    void drawBackground(QPainter *painter, const QRectF &rect);
    //void drawForeground(QPainter *painter, const QRectF &rect);
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    //void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);


    int mapWidth,mapHeight;

};

#endif
